package com.whl.sm.service.impl.expense;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whl.sm.common.result.Result;
import com.whl.sm.dto.ImportRecordDto;
import com.whl.sm.mapper.expense.MaterRecordMapper;
import com.whl.sm.model.assets.ComUnits;
import com.whl.sm.model.expense.ExpenseType;
import com.whl.sm.model.expense.MaterBill;
import com.whl.sm.model.expense.MaterRecord;
import com.whl.sm.service.assets.ComUnitsService;
import com.whl.sm.service.expense.ExpenseTypeService;
import com.whl.sm.service.expense.MaterBillService;
import com.whl.sm.service.expense.MaterRecordService;
import com.whl.sm.service.system.OrgUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wuhaolun
 * @since 2021-10-18
 */
@Service
@Slf4j
public class MaterRecordServiceImpl extends ServiceImpl<MaterRecordMapper, MaterRecord> implements MaterRecordService {

    @Autowired
    private ExpenseTypeService expenseTypeService;

    @Autowired
    private MaterBillService materBillService;

    @Autowired
    private OrgUserService orgUserService;

    @Autowired
    private ComUnitsService comUnitsService;

    @Override
    public Result update(MaterRecord materRecord) {
        try{
            materRecord.setOperator(orgUserService.getCurrentUserId());
            List<MaterRecord> hasLsit = getBaseMapper().selectList(new QueryWrapper<MaterRecord>()
                    .eq("unit_id",materRecord.getUnitId())
                    .eq("mater_type",materRecord.getMaterType())
                    .ne("is_del",1)
                    .orderByDesc("current_record_time")
            );
            insertByRecordTime(hasLsit,materRecord);
            if (materRecord.getCurrentRecord()<materRecord.getOldRecord()){
                return Result.build(444,"与以往记录有冲突，请检查");
            }
            if (materRecord.getId() == null){
                getBaseMapper().insert(materRecord);
            }else {
                getBaseMapper().updateById(materRecord);
            }
            return Result.ok();
        }catch (Exception e){
            log.error("抄表数据插入异常------------>"+e.getMessage());
            return Result.fail();
        }
    }

    @Override
    public Result addBillOfMater(String waterId , String electricId, List<String> idList) {
        ExpenseType water  = expenseTypeService.getById(waterId);
        ExpenseType electric  = expenseTypeService.getById(electricId);
        for (int i = 0; i < idList.size(); i++) {
            List<MaterBill> hasList = materBillService.list(new QueryWrapper<MaterBill>()
                    .eq("mater_record_id",idList.get(i)));
            if (hasList.size()>0){
                return Result.build(444,"该记录已生成账单");
            }
            MaterRecord materRecord = getById(idList.get(i));
            MaterBill insertBill = new MaterBill();
            double price = 0;
            if (materRecord.getMaterType() == 1){
                price = water.getUnitPrice()*(materRecord.getCurrentRecord()-materRecord.getOldRecord())
                        + water.getDefaultPrice();
                insertBill.setMaterType(1);
            }else {
                price = electric.getUnitPrice()*(materRecord.getCurrentRecord()-materRecord.getOldRecord())
                        + electric.getDefaultPrice();
                insertBill.setMaterType(0);
            }
            insertBill.setUnitId(materRecord.getUnitId());
            insertBill.setMaterRecordId(materRecord.getId());
            insertBill.setPaymentStatus(0);
            insertBill.setBillPrice(price);
            insertBill.setOperator("sys");
            Result insertResule = materBillService.update(insertBill);
            if (insertResule.getCode()!= 200){
                return insertResule;
            }
        }
        return Result.ok();
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRED)
    public Result beachAddRecord(List<ImportRecordDto> list) {
        StringBuffer errorInfo = new StringBuffer();
        try{
            int index  = 1;
            for (ImportRecordDto item : list){
                ComUnits linkUnit = comUnitsService.getByUnitCode(item.getUnitCode());
                if (Objects.isNull(linkUnit)){
                    errorInfo.append("第"+index+"行数据单元信息错误;");
                    continue;
                }
                MaterRecord insert = new MaterRecord();
                insert.setUnitId(linkUnit.getId());
                insert.setUnitCode(linkUnit.getUnitCode());
                insert.setCurrentRecord(item.getMaterRecord());
                insert.setCurrentRecordTime(item.getCurrentRecordTime());
                insert.setMaterType(item.getMaterType().equals("水表")?1:0);
                Result insertResult = update(insert);
                if (insertResult.getCode() == 444){
                    errorInfo.append("第"+index+"行数据:"+insertResult.getMessage()+";");
                }
            }
        }catch (Exception e){
            log.error("Excel表格数据导入异常:"+e.getMessage());
        }
        if (errorInfo.length()>0){
            return Result.build(444,errorInfo.toString());
        }
        return Result.ok();
    }


    private void insertByRecordTime(List<MaterRecord> hasList,MaterRecord target){
        if (hasList.size()>0){
            if (target.getCurrentRecordTime().getTime() > hasList.get(0).getCurrentRecordTime().getTime()) {
                hasList.stream().forEach(update->{
                    update.setOverdue(0);
                    getBaseMapper().updateById(update);
                });
                target.setOverdue(1);
            }
            else {
                target.setOverdue(0);
            }
            for (MaterRecord obj : hasList){
                if (target.getCurrentRecordTime().getTime()>obj.getCurrentRecordTime().getTime()){
                    target.setOldRecord(obj.getCurrentRecord());
                    target.setOldRecordTime(obj.getCurrentRecordTime());
                    break;
                }
            }
        }else {
            Calendar c=Calendar.getInstance();
            c.setTime(target.getCurrentRecordTime());
            c.add(Calendar.MONTH,-1);
            Date oldMonth =c.getTime();
            target.setOldRecordTime(oldMonth);
            target.setOldRecord((double) 0);
            target.setOverdue(1);
        }
    }



}
